package com.dao.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import com.bean.ArticleContext;
import com.bean.FollowObj;
import com.bean.UserLogin;
import com.bean.ZanMessage;
import com.dao.ArticleContextDao;
import com.util.CodeUtil;
import com.util.Domain;
import com.util.LoggerUtil;
import com.util.Pager;
@Component
public class ArticleContextDaoImpl implements ArticleContextDao{
	public static Logger logger=Logger.getLogger(ArticleContextDaoImpl.class);
	@Autowired
	private MongoTemplate mongoTemplate;
	@Override
	public Pager<ArticleContext> selectListByPageAreaArticle(Integer curPage,
			Integer pageSize, String areaId) {
		Pager<ArticleContext> pager=new Pager<ArticleContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
	    Criteria criteria=Criteria.where("areaId").is(new ObjectId(areaId));
		List<ArticleContext> data=mongoTemplate.find(
				new Query(criteria).skip(pager.getStart()).
					limit(pager.getPageSize()).with(new Sort(Sort.Direction.DESC,"rating")).
					with(new Sort(Sort.Direction.DESC,"publishDate")), 
					ArticleContext.class);
		pager.setData(data);
		long count=mongoTemplate.count(new Query(criteria), ArticleContext.class);
		pager.setTotalRow(Integer.valueOf(String.valueOf(count)));
		return pager;
	}
	@Override
	public Pager<ArticleContext> selectFollowArticle(Integer curPage,Integer pageSize,String id){
		UserLogin user=mongoTemplate.findById(id, UserLogin.class);
		List<ObjectId> strs=new ArrayList<ObjectId>();
		if(user!=null&user.getFollow()!=null){
			for(FollowObj obj:user.getFollow()){
				strs.add(new ObjectId(obj.getFollowId()));
			}
		}
		Criteria criteria=Criteria.where("users._id").in(strs);
		Pager<ArticleContext> pager=new Pager<ArticleContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
		List<ArticleContext> data=mongoTemplate.find(
				new Query(criteria).skip(pager.getStart()).
					limit(pager.getPageSize()).with(new Sort(Sort.Direction.DESC,"rating")).
					with(new Sort(Sort.Direction.DESC,"publishDate")), 
					ArticleContext.class);
		pager.setData(data);
		long count=mongoTemplate.count(new Query(criteria), ArticleContext.class);
		pager.setTotalRow(Integer.valueOf(String.valueOf(count)));
		return pager;
	}
	
	@Override
	public Pager<ArticleContext> selectOfficialListArticle(Integer curPage,
			Integer pageSize,String userId){
		Pager<ArticleContext> pager=new Pager<ArticleContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
		List<ArticleContext> data=mongoTemplate.find(
				new Query(Criteria.where("users._id").is(new ObjectId(userId))).skip(pager.getStart()).
					limit(pager.getPageSize()).with(new Sort(Sort.Direction.DESC,"rating")).
					with(new Sort(Sort.Direction.DESC,"publishDate")), 
					ArticleContext.class);
		long count=mongoTemplate.count(new Query(Criteria.where("users._id").is(new ObjectId(userId))), ArticleContext.class);
		pager.setData(data);
		pager.setTotalRow(Integer.valueOf(String.valueOf(count)));
		return pager;
	}
	@Override
	public Map<String, Object> updateZanNum(String id,String user_id){
		Map<String, Object> map=new HashMap<String, Object>();
		try {
			Query zanQuery=new Query(Criteria.where("types")
					.is(Domain.zan_message_types_zan).and("user_id").is(user_id).and("msg_id").is(id).and("is_delete").is(Domain.zan_message_is_delete_n)
					.and("text_types").is(Domain.zan_message_text_types_article));
			List<ZanMessage> zanMessages=mongoTemplate.find(zanQuery, ZanMessage.class);
			if(zanMessages!=null&&zanMessages.size()>0){
				mongoTemplate.updateMulti(zanQuery, new Update().set("is_delete", Domain.zan_message_is_delete_y), ZanMessage.class);
				Query query=new Query(Criteria.where("id").is(id));
				Update update=new Update();
				update.inc("zanNum2", -1);
				mongoTemplate.findAndModify(query, update, ArticleContext.class);
				map.put("code", "107");
				return map;
			}
			Query query=new Query(Criteria.where("id").is(id));
			Update update=new Update();
			update.inc("zanNum2", 1);
			mongoTemplate.findAndModify(query, update, ArticleContext.class);
			//ZanMessage zanMessage=new ZanMessage(Domain.zan_message_text_types_article,user_id,id,Domain.zan_message_is_delete_n,new Date());
			//mongoTemplate.insert(zanMessage);
			map.put("code", "0");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			map.put("code", "101");
		}
		return map;
	}
	@Override
	public Map<String, Object> findById(String id,String userId,JSONObject logs){
		Map<String, Object> map=new HashMap<String, Object>();
		try {
			ArticleContext articleContext=mongoTemplate.findById(id, ArticleContext.class);
			if(articleContext!=null){
				if(StringUtils.isNotEmpty(userId)){
					long count =mongoTemplate.count(new Query(Criteria.where("msg_id").
							is(id).and("user_id").is(userId).and("is_delete").is(Domain.zan_message_is_delete_n)), ZanMessage.class);
					if(count>0){
						articleContext.setIsZan("true");
					}else{
						articleContext.setIsZan("false");
					}
				}else{
					articleContext.setIsZan("false");
				}
				map.put("result", "success");
				map.put("rows",articleContext);
				LoggerUtil.backlogsSuccess(logs, logger);
			}else{
				map.put("result", "false");
				LoggerUtil.backlogsFalseNOData(logs, logger);
			}
		} catch (Exception e) {
			e.printStackTrace();
			map.put("code", "101");
			LoggerUtil.backlogsFalseError(logs, logger,e);
			return map;
		}
		return map;
	}
	
	
	public Pager<ArticleContext> selectFirstPageArticle(Integer curPage,Integer pageSize,Integer rating){
		Pager<ArticleContext> pager=new Pager<ArticleContext>();
		if(curPage!=null)
			pager.setCurPage(curPage);
		if(pageSize!=null)
			pager.setPageSize(pageSize);
		Query query=new Query()
			    .addCriteria(Criteria.where("rating").is(rating))
				.skip(pager.getStart()).
				limit(pager.getPageSize());
		List<ArticleContext> articles=mongoTemplate.find(query, ArticleContext.class);
		List<ArticleContext> data=new ArrayList<>();
		List<Integer> indexes=CodeUtil.randomIndexes1(articles.size());
		for(Integer index:indexes){
			data.add(articles.get(index));
		}
		long count=mongoTemplate.count(new Query(), ArticleContext.class);
		pager.setData(data);
		pager.setTotalRow(Integer.valueOf(String.valueOf(count)));
		return pager;
	}
	public List<ArticleContext> selectByFindRelate(String articleId) {
		ArticleContext article=mongoTemplate.findById(articleId, ArticleContext.class);
		Query query =new Query();
		if(article!=null){
			String uId=article.getUsers().getId();
			String []tags=article.getTag();
			if(tags!=null&&tags.length>0){
				Criteria []cts=new Criteria[2];
				cts[0]=Criteria.where("tag").in(Arrays.asList(tags));
				cts[1]=Criteria.where("users._id").is(new ObjectId(uId));
				query.addCriteria(new Criteria().orOperator(cts));
			}else{
				query.addCriteria(Criteria.where("users._id").is(new ObjectId(uId)));
			}
		}
		
		List<ArticleContext> articles=mongoTemplate.find(query.skip(0).limit(3), ArticleContext.class);
		List<ArticleContext> data=new ArrayList<>();
		List<Integer> indexes=CodeUtil.randomIndexes1(articles.size());
		for(Integer index:indexes){
			data.add(articles.get(index));
		}
		return data;
	}
}
